package controllers.security;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import com.google.gson.JsonObject;

import framework.base.BaseController;
import framework.base.PagerRS;
import framework.utils.CollectionUtil;
import framework.utils.DicUtil;
import framework.utils.MD5Util;
import framework.utils.SecurityUtil;
import framework.utils.StringUtil;
import models.security.Role;
import models.security.User;
import models.security.utils.SecurityConstant;
import models.security.vo.UserQuery;
import net.sf.json.JSONObject;
import play.Logger;
import play.data.binding.ParamNode;
import play.data.validation.Valid;
import play.mvc.After;
import play.mvc.Controller;

public class Users extends BaseController {
    
    /**
     * 列表页
     * @param page
     * @param query
     */
    public static void index(Integer page, UserQuery query){
        PagerRS<User> rs = (PagerRS<User>) User.findByPager(getQuery(query, UserQuery.class), getPageNo(page),
                getPageSize());
        render(rs);
    }
    
    /**
     * 用户新增
     */
    public static void add(){
        Map editData = buildEditData(1, null, null);
        render(editData);
    }
    
    /**
     * 创建用户
     * @param user
     */
    public static void create(@Valid User user,String[] rids){
        if(validation.hasErrors()){
            Map editData = buildEditData(3, null, rids);
            saveUserLogAndNotice("用户创建失败", false);
            render("@add",editData);
        }else{
            String loginerId = SecurityUtil.getLoginUserId();
            user.creatorId = loginerId;
            user.operatorId = loginerId;
            if(StringUtil.isBlank(user.securityKey)){
                user.securityKey = UUID.randomUUID().toString();
            }
            user.password = MD5Util.encodeToStr(user.password + user.securityKey);
            user.assignRoles(rids);
            user.save();
            saveUserLogAndNotice("用户创建成功", true);
            index(null,null);
        }

    }
    
    /**
     * 编辑用户
     * @param id
     */
    public static void edit(String id){
        User user = User.findById(id);
        Map editData = buildEditData(2, user, null);
        render(user,editData);
    }
    
    /**
     * 用户更新
     * @param id
     */
    public static void update(String id,String[] rids){
        User user = User.findById(id);
        String oldPassword = StringUtil.trim(user.password);
        user.edit(ParamNode.convert(params.all()), "user");
        if (!oldPassword.equals(StringUtil.trim(user.password))) {
            user.password = MD5Util.md5Encode(user.password.trim() + user.securityKey);
            user.confirmPassword = MD5Util.md5Encode(user.confirmPassword.trim() + user.securityKey);
        }
        validation.valid(user);
        if(validation.hasErrors()){
            Map editData = buildEditData(3, user, null);
            saveUserLogAndNotice("用户更新失败", false);
            render("@edit",user,editData);
        }else{
            String loginerId = SecurityUtil.getLoginUserId();
            user.updatedAt = new Date();
            user.operatorId = loginerId;
            user.assignRoles(rids);
            user.save();
            saveUserLogAndNotice("用户创建成功", true);
            index(null,null);
        }
    }
    
    /**
     * 用户删除
     * @param id
     */
    public static void destroy(String id){
        User user = User.findById(id);
        if(null != user){
            String loginerId = SecurityUtil.getLoginUserId();
            user.operatorId = loginerId;
            user.revoke();
            user.destroy();
            saveUserLogAndNotice("用户删除成功", true);
        }else{
            saveUserLogAndNotice("用户删除失败", false); 
        }
       index(null,null);
    }

    /**
     * 用户查看
     * @param id
     */
    public static void show(String id){
        User user = User.findById(id);
        render(user);
    }
    
    
    /**
     * @param buildType
     *            1:添加 2：修改3：失败
     */
    private static Map buildEditData(int buildType, User user, String[] rids) {
        Map map = new HashMap();
        Map<String, String> roles = null;
        roles = DicUtil.getAllByDicName(SecurityConstant.DIC_ROLE_LIST_NAME);
        String rid = "";
        if (buildType == 1 || buildType == 3) {
            rid = CollectionUtil.join(rids, ",");
        } else {
            rid = CollectionUtil.joinEnitiy(user.roles, null, Role.class, "id");
        }
        if (!rid.equals("")) {
            map.put("rids", CollectionUtil.getMapFromKeys(roles, rid.split(","), String.class));
            roles = CollectionUtil.removeByKeys(roles, rid.split(","), String.class);
        }
        map.put("roles", roles);
        return map;
    }
    
    public static void profile(){
        String uid = SecurityUtil.getLoginUserId();
        if(StringUtil.isBlank(uid)){
            redirect("Application.index");
        }else{
          User user  = User.findById(uid);
          render(user);
        }
    }
    
    public static void updateProfile(String id){
        User user = User.findById(id);
        int rcode = 0;
        if(null!=user){
            String oldPassword = user.password;
            String _old = StringUtil.trim(params.get("oldPassword"));
            String _new = StringUtil.trim(params.get("newPassword"));
            String _oldPwd = MD5Util.md5Encode(_old+user.securityKey);
            if(oldPassword.equals(_oldPwd)){
                _new = MD5Util.md5Encode(_new+user.securityKey);
                user.password = _new;
                user.save();
            }else{
                rcode = 1;
            }
        }else{
            rcode = 2;
        }
        JSONObject obj = new JSONObject();
        obj.put("rcode", rcode);
        renderJSON(obj);
    }
    
    @After(only = { "security.Users.create", "security.Users.update", "security.Users.destroy" })
    public static void lifeCycle() {
            DicUtil.loadByDicName(SecurityConstant.DIC_USER_LIST_NAME);
            DicUtil.loadByDicName(SecurityConstant.DIC_ALL_USER_LIST_NAME);
    }
    
}
